/**
 * 类名：FileService
 * 创建日期： 2014-11-12 下午7:51:13
 * 
 */
package com.erms.domain;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;

import com.erms.bean.FileInfo;
import com.erms.bean.User;
import com.erms.dao.FileInfoDAO;
import com.erms.util.LogUtil;
import com.erms.util.StringUtil;
import com.erms.util.TimeUtil;
import com.erms.util.office.MSPowerPoint;
import com.erms.util.office.MSWord;

/**
 * @author hmb
 *         备注：不要手动调用本类中的方法，文件操作已油其他专用service类维护
 * 
 */
public class FileService {
	final protected Logger			logger						= LogUtil
																		.getLogger(getClass());
	protected static String			rootPath					= null;
	final protected static String	PATH_COURSEWARE				= "/courseware";
	final protected static String	PATH_TASK					= "/task";
	final protected static String	PATH_MESSAGE				= "/message";
	final private static String		PATH_HOMEWORK				= "/homework";

	final public static int			TYPE_COURSEWARE_ATTACH_FILE	= 0;
	final public static int			TYPE_TASK_ATTACH_FILE		= 1;
	final public static int			TYPE_MESSAGE_ATTACH_FILE	= 2;
	final public static int			TYPE_HOMEWORK_ATTACH_FILE	= 3;

	private FileInfoDAO				fileInfoDAO;
	private FileInfo				fileInfo;

	private File					srcFile;

	protected String				desFileName;												// 目的文件名，不带后缀和路径
	protected String				desFilePath;												// 目的文件路径
	protected String				suffix;													// 后缀名

	public FileInfo getFileInfo() {

		return fileInfo;
	}

	public void setFileInfo(FileInfo fileInfo) {

		this.fileInfo = fileInfo;
	}

	public FileInfoDAO getFileInfoDAO() {

		return fileInfoDAO;
	}

	public void setFileInfoDAO(FileInfoDAO fileInfoDAO) {

		this.fileInfoDAO = fileInfoDAO;
	}

	public static String getRootPath() {

		return rootPath;
	}

	public String getTaskAttachFilePath() {

		return PATH_TASK;
	}

	public String getMessageAttachFilePath() {

		return PATH_MESSAGE;
	}

	public String getHomeworkAttachFilePath() {

		return PATH_HOMEWORK;
	}

	public String getDesFileName() {

		return desFileName;
	}

	public String getDesFilePath() {

		return desFilePath;
	}

	public String getSuffix() {

		return suffix;
	}

	private void init(File srcFile, String srcFileName, String newFileName,
			int type) {

		this.srcFile = srcFile;
		int index = srcFileName.lastIndexOf(".");
		if (index >= 0) {
			this.suffix = srcFileName.substring(index + 1);
			this.desFileName = srcFileName.substring(0, index);
		} else {
			this.desFileName = srcFileName;
		}

		if (!StringUtil.isNull(newFileName)) {
			this.desFileName = newFileName;
		}
		switch (type) {
			case TYPE_COURSEWARE_ATTACH_FILE :
				this.desFilePath = PATH_COURSEWARE;
				break;
			case TYPE_HOMEWORK_ATTACH_FILE :
				this.desFilePath = PATH_HOMEWORK;
				break;
			case TYPE_MESSAGE_ATTACH_FILE :
				this.desFilePath = PATH_MESSAGE;
				break;
			case TYPE_TASK_ATTACH_FILE :
				this.desFilePath = PATH_TASK;
				break;
			default :
				this.desFilePath = null;
				break;
		}
	}

	/**
	 * 保存文件，不要手动调用这个方法
	 * 
	 * @param srcFile 文件
	 * @param srcFileName 文件名
	 * @param srcContentType 文件类型
	 * @param newFileName 新文件名
	 * @param description 文件描述
	 * @param type 文件类型 {@link FileService.TYPE_XXX}
	 * @param userID 上传者ID
	 * @return
	 */
	public boolean save(File srcFile, String srcFileName,
			String srcContentType, String newFileName, String description,
			int type, String userID) {

		if (srcFile == null) {
			fileInfo = null;
			//不需要保存文件
			return true;
		}
		try {
			this.init(srcFile, srcFileName, newFileName, type);
			this.saveFile();
			User user = new User(userID, null, null);
			fileInfo = new FileInfo();
			fileInfo.setUser(user);
			fileInfo.setTimestamp(TimeUtil.getTimeStamp());
			fileInfo.setPath(this.desFilePath);
			fileInfo.setName(this.desFileName);
			fileInfo.setSize(srcFile.length());
			fileInfo.setType(srcContentType);
			fileInfo.setDescription(description);
			fileInfoDAO.save(fileInfo);
		} catch (Exception e) {
			// TODO: handle exception
			logger.debug("保存文件失败", e);
			return false;
		}
		return true;
	}

	private boolean saveFile() {

		try {
			if (StringUtil.isNull(rootPath)) {
				// rootPath =
				// "C:/Users/hmb/Documents/MyEclipse Professional/.metadata/.me_tcat7/webapps/erms/file";
				rootPath = ServletActionContext.getServletContext()
						.getRealPath("/file");
			}
			File filePath = new File(rootPath + this.desFilePath);
			if (!filePath.exists()) {
				filePath.mkdirs();
			}

			while (true) {
				String randomString = StringUtil.random();
				String temp = this.desFileName + "_" + randomString + "."
						+ this.suffix;
				if (!new File(rootPath + this.desFilePath + "/" + temp)
						.exists()) {
					this.desFileName = temp;
					break;
				}
				logger.debug("文件名已存在" + temp);
			}

			String fullName = rootPath + this.desFilePath + "/"
					+ this.desFileName;

			logger.debug("文件全名：" + fullName);

			FileOutputStream fos = new FileOutputStream(fullName);
			FileInputStream fis = new FileInputStream(this.srcFile);

			byte[] buffer = new byte[8192];// 每次读8k字节
			int count = 0;
			while ((count = fis.read(buffer)) > 0) {
				fos.write(buffer, 0, count);
			}
			fos.close();
			fis.close();
		} catch (Exception e) {
			logger.debug("保存文件失败", e);
			return false;
		}
		logger.debug("文件上传成功");
		return true;
	}

	/**
	 * 删除文件，不要手动调用此方法
	 * 
	 * @param fileInfoID 文件ID
	 * @return
	 */
	public boolean delete(Integer fileInfoID) {

		boolean result = true;
		try {

			String path = getFilePath(fileInfoID);
			logger.debug("即将删除文件：" + path);
			File file = new File(path);
			if (!file.exists()) {
				logger.debug("文件不存在");
			} else {
				// 删除文件
				file.delete();
			}
			// 删除数据库信息
			fileInfoDAO.delete(fileInfo);

		} catch (Exception e) {
			// TODO: handle exception
			logger.debug("删除文件信息失败");
			result = false;
		}
		return result;
	}

	public InputStream download(Integer id){

		
		String path = getFilePath(id);
		logger.debug("即将下载文件：" + path);
		try {
			return new FileInputStream(path);
		} catch (FileNotFoundException e) {
			// TODO 自动生成的 catch 块
			logger.error("download + FileNotFoundException",e);
		}
		return null;
	}
	public InputStream previewIMG(Integer id) {
		
		String path = getFilePath(id);
		logger.debug("即将预览文件：" + path);
		try {
			return new FileInputStream(path);
		} catch (FileNotFoundException e) {
			// TODO 自动生成的 catch 块
			logger.error("FileNotFoundException",e);
		}
		return null;
	}
	public String previewTEXT(Integer id) {

		String path = getFilePath(id);
		logger.debug("预览文件：" + path);
		StringBuilder sb = new StringBuilder();
		try {
			FileInputStream fis = new FileInputStream(path);
			String charset = getCharset(path);

			logger.debug("该文件编码可能为" + charset);

			InputStreamReader reader = new InputStreamReader(fis, charset);
			BufferedReader br = new BufferedReader(reader);
			String temp = null;
			while ((temp = br.readLine()) != null) {
				sb.append(temp);
				sb.append("<br/>");
			}
			br.close();
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			logger.error("FileNotFoundException", e);
		}
		return sb.toString();
	}
	public String previewWord(Integer id) {
		String path = getFilePath(id);
		logger.debug("预览word文件：" + path);
		MSWord word = new MSWord(path,"utf-8");
		return word.toHtml();
	}
	
	public List<Map<String, String>> previewPPT(Integer id){

		String path = getFilePath(id);
		try {
			return new MSPowerPoint(path, "utf-8").toJpg();
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			logger.error("previewPPT + Exception",e);
		}
		return null;
	}

	public FileInfo find(Integer id) {

		return fileInfoDAO.findById(id);
	}

	private String getCharset(String path) {

		String charset = "GBK";
		try {
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
			int p = (bis.read() << 8) + bis.read();
			switch (p) {
				case 0xefbb :
					charset = "UTF-8";
					break;
				case 0xfffe :
					charset = "Unicode";
					break;
				case 0xfeff :
					charset = "UTF-16BE";
					break;
				default :
					if (path.endsWith(".java") || path.endsWith(".sql")) {
						charset = "UTF-8";
						logger.debug("java文件默认为utf-8");
					}
					break;
			}
			//bis.reset();
			bis.close();
		} catch (IOException e) {
			logger.error("getCharset + IOException", e);
		}

		return charset;

	}

	private String getFilePath(Integer id) {

		fileInfo = fileInfoDAO.findById(id);
		if (fileInfo == null) {
			logger.debug("没有找到文件");
			return null;
		}
		if (StringUtil.isNull(rootPath)) {
			rootPath = ServletActionContext.getServletContext().getRealPath(
					"/file");
		}
		String path = rootPath + fileInfo.getPath() + "/" + fileInfo.getName();
		return path;
	}
}
